package com.lvm.app.task;


import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.lvm.app.api.entity.LvmFileRec;
import com.lvm.app.api.entity.LvmTopicRec;
import com.lvm.app.config.LvmProperties;
import com.lvm.app.dao.LvmFileRecMapper;
import com.lvm.app.dao.LvmTopicRecMapper;
import com.lvm.app.dto.FileListDTO;
import com.lvm.app.file.*;
import com.lvm.app.util.CreateMd5;
import lombok.Data;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;


import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;


@Data
public class VideoTask extends Thread{
    private List<TopicFileInfo> topics;
    private Double process = 0d;
    private String taskId;
    private int taskType;
    private int status;
    private String taskName = "---";
    private FileUtil fileUtil;
    private StringBuilder curMessage = new StringBuilder();
    private String outDir;
    @JsonIgnore
    private LvmFileRecMapper lvmFileRecMapper;
    @JsonIgnore
    private LvmTopicRecMapper lvmTopicRecMapper;
    private int captureNumber = 8;

    private static Logger logger = LoggerFactory.getLogger(VideoTask.class);

    public VideoTask(String outDir, ApplicationContext application){
        this.lvmFileRecMapper = (LvmFileRecMapper) application.getBean("lvmFileRecMapper");
        this.lvmTopicRecMapper = (LvmTopicRecMapper) application.getBean("lvmTopicRecMapper");
        this.taskId = UUID.randomUUID().toString();
        this.outDir = outDir;
        fileUtil = FileUtil.getInstance();
    }


    @Override
    public void run() {
        taskMessage("执行任务 开始:"+topics.size());
        status = 1;//进行中
        int size = topics.size();
        int o = 1;
       try{
           Iterator<TopicFileInfo> ite =  topics.iterator();
            while(ite.hasNext()){
                TopicFileInfo topic = ite.next();
               if(status==3){//取消执行
                   return;
               }
               taskMessage("执行任务 路径:"+topic.getRootPath()+"---第"+o+"个任务"+"还有："+(size-o));
               LvmTopicRec topicRec = new LvmTopicRec();
               List<LvmFileRec> thumbs = new ArrayList<>();
               List<LvmFileRec> videoFiles = this.fileMove(topic.getVideoFiles(),thumbs);
                boolean exists = videoFiles.stream().anyMatch((item)->{
                    return item.isFileExists();
                });
                if(exists){
                      continue;
                }

               List<LvmFileRec> pictures = this.fileMove(topic.getPicFiles(),null);
                if(topic.getVideoFiles().size()==0){
                    boolean picExists = pictures.stream().anyMatch((item)->{
                        return item.isFileExists();
                    });
                    if(picExists){
                        continue;
                    }
                }
               topicRec.setTitle(topic.getTitle());
               topicRec.setBodyHtml("");
               topicRec.setThumbList(JSONObject.toJSONString(parseFileList(thumbs)));
               topicRec.setVideoList(JSONObject.toJSONString(parseFileList(videoFiles)));
               topicRec.setPicList(JSONObject.toJSONString(parseFileList(pictures)));
               topicRec.setThumbListObj(thumbs);
               topicRec.setVideoListObj(videoFiles);
               topicRec.setPicListObj(pictures);
               topicRec.setPosterUrl("");
               topicRec.setHits(0l);
               topicRec.setScore(0);
               topicRec.setDescription("");
               topicRec.setClassifyId(0l);
               topicRec.setKeyList("");
               topicRec.setCoverPic("");
               topicRec.setStatus(-1);
               topicRec.setRelList("");
               topicRec.setType(1);
               topicRec.setClassifyId(0l);
               topicRec.setCoverVideo("");
               lvmTopicRecMapper.insert(topicRec);
               topic.setTopicRec(topicRec);
               process++;
                o++;
               ite.remove();
           }
           status = 2;
       }catch (Exception e){
           e.printStackTrace();
       }
        taskMessage("执行任务 结束");

    }

    String parseTitle(String title){
        return title.split("\\\\")[0];
    }

    private List<LvmFileRec> fileMove(List<File> files,List<LvmFileRec> thumbs) throws Exception {
        List<LvmFileRec> mFiles = new ArrayList<LvmFileRec>();
        for (File f:files){
            StringBuilder md5  = CreateMd5.createMd5(f);
            List<LvmFileRec> dbFile = lvmFileRecMapper.selectList(Wrappers.<LvmFileRec>lambdaQuery().eq(LvmFileRec::getMd5,md5.toString()));
            if(dbFile.size()>0){
                dbFile.get(0).setFileExists(true);
                mFiles.add(dbFile.get(0));
                if(FileTypeCheck.checkFileType(f)==FileType.VIDEO){
                    List<LvmFileRec> thumbRecs = lvmFileRecMapper.selectList(Wrappers.<LvmFileRec>lambdaQuery().eq(LvmFileRec::getParentFileNo,dbFile.get(0).getFileNo()));
                    thumbs.addAll(thumbRecs);
                }
                continue;
            }else{
                File file2 = fileUtil.saveFile(f, outDir, null,taskId,(message)->{
                    taskMessage(message);
                });
                LvmFileRec fileRec = new LvmFileRec();
                fileRec.setMd5(md5.toString());
                fileRec.setFileNo(UUID.randomUUID().toString());
                fileRec.setFileDir(fileUtil.getPath(outDir,file2));
                fileRec.setFileUrl(f.getName());
                fileRec.setHisFileDir(f.getPath());
                fileRec.setIndexId(1);
                fileRec.setSuffix(fileUtil.getSuffix(file2));
                fileRec.setFileType(1);
                fileRec.setVideoTimeLong(0l);
                fileRec.setParentFileNo("");
                lvmFileRecMapper.insert(fileRec);
                mFiles.add(fileRec);
                if(FileTypeCheck.checkFileType(f)==FileType.VIDEO){
                    taskMessage("截图开始");
                    List<String> picFilesDir = FFmpegUtils.capturePic(file2,file2.getPath(),captureNumber,LvmProperties.getFfmpeg(),(duration)->{//视频时长
                        fileRec.setVideoTimeLong(duration);
                        lvmFileRecMapper.updateById(fileRec);
                    });
                    List<File> picFiles = picFilesDir.stream().map((picItem)->{
                        File itemFile = new File(picItem);
                        return itemFile;
                    }).collect(Collectors.toList());
                    taskMessage("截图结束");
//                    List<File> picFiles = VideoF.getInstance().capturePicture(file2,file2.getParent()+File.separator+"thumb",fileUtil.getName(file2)+"_thumb",captureNumber,(message)->{
//                        taskMessage(message);
//                    },(duration)->{//视频时长
//                        fileRec.setVideoTimeLong(duration);
//                        lvmFileRecMapper.updateById(fileRec);
//                    });
                    if(picFiles!=null&&picFiles.size()>0){
                        for(File pic:picFiles){
                            StringBuilder md5Pic = CreateMd5.createMd5(pic);
                            LvmFileRec fileRec2 = new LvmFileRec();
                            fileRec2.setMd5(md5Pic.toString());
                            fileRec2.setFileNo(UUID.randomUUID().toString());
                            fileRec2.setFileDir(fileUtil.getPath(outDir,pic));
                            fileRec2.setFileUrl(f.getName());
                            fileRec2.setIndexId(1);
                            fileRec2.setParentFileNo(fileRec.getFileNo());
                            fileRec2.setSuffix(fileUtil.getSuffix(pic));
                            fileRec2.setFileType(3);
                            lvmFileRecMapper.insert(fileRec2);
                            if(thumbs!=null){
                                thumbs.add(fileRec2);
                            }
                        }
                    }
                }

            }

        }
        return mFiles;
    }
    private void taskMessage(String message){
        if(curMessage.length()>2000){
            curMessage.delete(0,curMessage.length()-2000);
        }
        //this.curMessage.append("</br>").append(DateUtil.now()+":"+message);
        logger.info("执行任务"+"  :"+message);
    }

    private List<FileListDTO> parseFileList(List<LvmFileRec> fileRecs){
        List<FileListDTO> res = new ArrayList<>();
         for(LvmFileRec d :fileRecs){
             FileListDTO s = new FileListDTO();
             s.setFileDir(d.getFileDir());
             s.setFileNo(d.getFileNo());
             s.setType(d.getFileType());
             s.setFileUrl(d.getFileUrl());
             s.setVideoTimeLong(d.getVideoTimeLong());
             res.add(s);
         }
         return res;
    }
    @Test
    public void test(){
        TopicFileSum sumExecutor = new TopicFileSum();
        List<TopicFileInfo> to = sumExecutor.fileDirIterator(new File("C:\\Users\\admin\\Documents"));
        System.out.println(JSONObject.toJSONString(to));
    }
}
